from django.contrib import admin

# Register your models here.
import logging
from urllib.parse import urljoin
from django.shortcuts import redirect
from django.utils import timezone
from django.utils import http
from django.urls import reverse

from log_audit import models
from log_audit.filters import (
    LogProcessingAutoTagListFilter,
    SeverityListFilter, FacilityListFilter, ProcessListFilter, HostListFilter,
    ProcessParsedLogListFilter, MyDateFieldListFilter,
)

from utils.auto_audit import auto_tag

logger = logging.getLogger(__name__)


class ParsedLogAdmin(admin.ModelAdmin):
    list_display = ("time", "host", "severity", "facility", "process", "message")
    search_fields = ('message',)
    list_filter = ("host", ('time', MyDateFieldListFilter),
                   "severity", "facility",
                   ProcessParsedLogListFilter)
    list_per_page = 100
    date_hierarchy = "time"
    actions = ('create_log_processing',)

    def create_log_processing(self, request, queryset):
        q_count = len(queryset)
        logger.info("从 %s 选择了 %s 条记录" % (self.opts.verbose_name_plural, q_count))
        queryset = queryset.order_by('time')
        # 去重
        dup_dic = {}
        for q in queryset:
            key = q.dup_tuple
            if key in dup_dic:
                dup_dic[key]['count'] += 1
                dup_dic[key]['last_log'] = q
            else:
                dup_dic[key] = {'first_log': q, 'last_log': q, 'count': 1}
        target_model = models.LogProcessing  # 要操作的表的类
        # 批量创建记录
        obj_list = []
        for o in dup_dic.values():
            obj_list.append(target_model(
                first_log=o['first_log'],
                last_log=o['last_log'],
                count=o['count'],
                auto_tag=auto_tag(o),
            ))
        o_count = len(obj_list)
        logger.info("批量创建记录到 %s，原纪录 %s 条，去重后 %s 条" % (
            target_model._meta.verbose_name_plural, q_count, o_count))
        target_model.objects.bulk_create(obj_list)

        # 在页面上生成消息
        self.message_user(request, '原记录 %s 条，去重后创建了 %s 条记录' % (q_count, o_count))

        # 生成跳转的url
        base_url = reverse('admin:app_list', kwargs={'app_label': target_model._meta.app_label})
        now = timezone.localtime(timezone.now())
        field_name = 'c_time'
        url_params = http.urlencode({field_name + '__day': now.day,
                                     field_name + '__month': now.month,
                                     field_name + '__year': now.year})
        target_url = '%s?%s' % (urljoin(base_url, target_model._meta.model_name), url_params)

        return redirect(target_url)
    create_log_processing.short_description = "创建处理记录"


class LogProcessingAdmin(admin.ModelAdmin):
    list_display = ("first_log_time", 'last_log_time', 'count',
                    "host", "severity", "facility", "process", "message",
                    "handling_status", "auto_tag", "c_time")
    search_fields = ('last_log__message',)
    list_editable = ("handling_status",)
    list_filter = ("handling_status", LogProcessingAutoTagListFilter, "c_time",
                   HostListFilter,
                   SeverityListFilter, FacilityListFilter, ProcessListFilter)
    list_per_page = 100
    date_hierarchy = "c_time"
    actions = ('set_handling_status', 'sum_count', 'check_auto_audit')
    empty_value_display = '未标记'

    def set_handling_status(self, request, queryset):
        """批量设置handling_status字段的值"""
        count = len(queryset)  # update方法执行后，数量会变成0
        # status = queryset.first().handling_status
        status = "已处理"
        queryset.update(handling_status=status)
        self.message_user(request, '共 %s 条记录设置为 %s' % (count, status))
    set_handling_status.short_description = "批量设置为 已处理"

    def sum_count(self, request, queryset):
        from django.db.models import Sum
        count_all = queryset.aggregate(count=Sum('count'))['count']  # aggregate 是聚合函数
        count_auto_tag_ignored = queryset.filter(auto_tag="忽略").aggregate(count=Sum('count'))['count']
        # 如果过滤后没有记录，会返回None。然后提交给aggregate，最后还是None
        self.message_user(request, "总数量: %d, 标记忽略: %d" % (count_all, count_auto_tag_ignored or 0))
    sum_count.short_description = "计算总数和处理数"

    def check_auto_audit(self, request, queryset):
        for q in queryset:
            obj = {}
            obj.setdefault('first_log', q.first_log)
            obj.setdefault('last_log', q.last_log)
            obj.setdefault('count', q.count)
            tag = auto_tag(obj)
            if tag:
                self.message_user(request, "%s: %s" % (tag, q))
            else:
                self.message_user(request, "%s: %s" % ("没有匹配", q))
    check_auto_audit.short_description = "验证自动审计规则"


class AutoAuditRuleAdmin(admin.ModelAdmin):
    list_display = ('c_time', 'type', 'name', 'auto_tag', 'comments')


admin.site.register(models.ParsedLog, ParsedLogAdmin)
admin.site.register(models.LogProcessing, LogProcessingAdmin)
admin.site.register(models.AutoAuditRule, AutoAuditRuleAdmin)



